package cn.melon.bz;

import java.io.EOFException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;

import org.apache.log4j.Logger;

import cn.melon.Helper.LoggerHelper;
import cn.melon.base.BaseController;
import cn.melon.common.Message;
import cn.melon.mod.dorm.DormController;
import cn.melon.mod.library.LibraryController;
import cn.melon.mod.login.UserInfo;
import cn.melon.mod.roll.RollController;
import cn.melon.mod.sc.ScController;
import cn.melon.mod.store.StoreController;

/**
 * 用户登录成功之后, 每个用户将会被分配一个该线程, 该线程将会记录用户资料, 并保存socket信息<br>
 *               线程交由{@link cn.melon.bz.ClientThreadMgr}进行管理
 * @ClassName: ClientThread
 * @author corvo
 */
public class ClientThread extends Thread {

    private final String TAG = LoggerHelper.makeLogTag(ClientThread.class);
    private Logger threadLogger = LoggerHelper.serverLogger();

    /**
     * 客户端socket信息
     */
    private Socket client;
    /**
     * 与此socket线程相关联的用户信息
     */
    private UserInfo userInfo;
    /**
     * 服务器通过检查该变量来确定客户端是否断开连接
     */
    private boolean isClosed;

    public ClientThread(Socket s, UserInfo userInfo) {
        this.client = s;
        this.isClosed = false;
        this.userInfo = userInfo;
    }

    @Override
    public void run() {

        while (!isClosed) {
            try {
                ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
                Message msg = (Message) ois.readObject();

                BaseController controller = null;
                switch (msg.getModelType()) {
                    case ROLL:
                        controller = new RollController(msg.getData());
                        break;
                    case LIBRARY:
                        controller = new LibraryController(msg.getData());
                        break;
                    case STORE:
                        controller = new StoreController(msg.getData());
                        break;
                    case COURSE:
                        controller = new ScController(msg.getData());
                        break;
                    case DORM:
                        controller = new DormController(msg.getData());
                        break;
                    default:
                        break;
                }

                if (controller == null) {   // 请求未知的类型
                    threadLogger.info(TAG + userInfo.getStudentNum() + " Unknow action!!");
                    continue;
                }

                controller.setUserInfo(this.userInfo);  // 设置用户信息
                controller.makeResponse();              // 调用处理函数

                msg.setData(controller.getResponse());

                ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());

                oos.writeObject(msg);
                oos.flush();

            } catch (SocketException e) {
                this.isClosed = true;       // 重置isClosed变量
                threadLogger.info(TAG + userInfo.getStudentNum() + " 已经退出");
            } catch (EOFException e) {
                this.isClosed = true;       // 重置isClosed变量
                threadLogger.info(TAG + userInfo.getStudentNum() + " 已经退出");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void close() {
        isClosed = true;
    }
}
